package com.shunda.trade.service.impl;

import com.shunda.common.core.domain.entity.SysDept;
import com.shunda.common.core.domain.entity.SysUser;
import com.shunda.common.utils.StringUtils;
import com.shunda.system.mapper.SysDeptMapper;
import com.shunda.system.mapper.SysUserMapper;
import com.shunda.system.service.ISysConfigService;
import com.shunda.trade.constant.TradeConstants;
import com.shunda.trade.entity.TradeOrder;
import com.shunda.trade.entity.TradeProfitFlow;
import com.shunda.trade.entity.TradeUserProfit;
import com.shunda.trade.mapper.TradeOrderMapper;
import com.shunda.trade.mapper.TradeProfitFlowMapper;
import com.shunda.trade.mapper.TradeUserProfitMapper;
import com.shunda.trade.service.TradeProfitFlowService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 用户信息表(TradeProfitFlow)表服务实现类
 *
 * @author makejava
 * @since 2025-03-13 21:36:53
 */
@Service("tradeProfitFlowService")
public class TradeProfitFlowServiceImpl implements TradeProfitFlowService {
    @Resource
    private TradeProfitFlowMapper tradeProfitFlowDao;

    @Resource
    private TradeOrderMapper tradeOrderDao;

    @Resource
    private SysDeptMapper sysDeptMapper;
    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private TradeUserProfitMapper tradeUserProfitDao;

    @Autowired
    private ISysConfigService configService;

    private static final Logger log = LoggerFactory.getLogger(TradeProfitFlowServiceImpl.class);
    /**
     * 通过ID查询单条数据
     *
     * @param profitId 主键
     * @return 实例对象
     */
    @Override
    public TradeProfitFlow queryById(Long profitId) {
        return this.tradeProfitFlowDao.queryById(profitId);
    }

    /**
     * 分页查询
     *
     * @param tradeProfitFlow 筛选条件
     * @param pageRequest     分页对象
     * @return 查询结果
     */
    @Override
    public Page<TradeProfitFlow> queryByPage(TradeProfitFlow tradeProfitFlow, PageRequest pageRequest) {
        long total = this.tradeProfitFlowDao.count(tradeProfitFlow);
        return new PageImpl<>(this.tradeProfitFlowDao.queryAllByLimit(tradeProfitFlow, pageRequest), pageRequest, total);
    }

    /**
     * 新增数据
     *
     * @param tradeProfitFlow 实例对象
     * @return 实例对象
     */
    @Override
    public TradeProfitFlow insert(TradeProfitFlow tradeProfitFlow) {
        this.tradeProfitFlowDao.insert(tradeProfitFlow);
        return tradeProfitFlow;
    }

    /**
     * 修改数据
     *
     * @param tradeProfitFlow 实例对象
     * @return 实例对象
     */
    @Override
    public TradeProfitFlow update(TradeProfitFlow tradeProfitFlow) {
        this.tradeProfitFlowDao.update(tradeProfitFlow);
        return this.queryById(tradeProfitFlow.getProfitId());
    }

    /**
     * 通过主键删除数据
     *
     * @param profitId 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Long profitId) {
        return this.tradeProfitFlowDao.deleteById(profitId) > 0;
    }

    @Override
    public void calculateMoney() {
        try {
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            SimpleDateFormat ds = new SimpleDateFormat("yyyy-MM-dd ");
            // 获取当前日期
            Date currentDate = new Date();
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(currentDate);
            // 获取30天前的日期
            calendar.add(Calendar.DAY_OF_MONTH, -1);
            Date yesterDay = calendar.getTime();
            String startTimeStr = new String();
            String endTimeStr = new String();

            Date startTime = df.parse(ds.format(yesterDay) + "00:00:00");
            startTimeStr = df.format(startTime);
            Date endTime = df.parse(ds.format(currentDate) + "00:00:00");
            endTimeStr = df.format(endTime);


            BigDecimal yesterDayBalance = BigDecimal.valueOf(0);
            //结余
            TradeProfitFlow tradeProfitFlow = tradeProfitFlowDao.selectLastDayBalance();
            if (tradeProfitFlow != null) {
                yesterDayBalance = yesterDayBalance.add(BigDecimal.valueOf(tradeProfitFlow.getUserProfitAmount()));
            }
            //查当天所有收入
            List<TradeProfitFlow> allIncomeToday = tradeProfitFlowDao.selectAllIncomeToday(startTimeStr, endTimeStr);

            //昨日所有用户分润总金额
            BigDecimal total = BigDecimal.ZERO;
            for (TradeProfitFlow profitFlow : allIncomeToday) {
                //订单id
                Long orderId = profitFlow.getOrderId();
                //订单
                TradeOrder tradeOrder = tradeOrderDao.queryById(orderId);
                //加油站id
                Long deptId = tradeOrder.getDeptId();
                //加油站
                SysDept sysDept = sysDeptMapper.selectDeptById(deptId);
                //加油站可提现金额
                BigDecimal deptProfit = sysDept.getProfit();
                //订单分润总金额
                BigDecimal profitAmount = BigDecimal.valueOf(profitFlow.getProfitAmount());

                //每笔订单加油站可分润金额
                String deptProportion = configService.selectConfigByKey("deptProportion");
                BigDecimal deptProfitAmount = profitAmount.multiply(new BigDecimal(deptProportion));
                //更新每一个加油站可提现金额
                SysDept sysDeptUpdate = new SysDept();
                sysDeptUpdate.setDeptId(deptId);
                deptProfit = deptProfit.add(deptProfitAmount);
                sysDeptUpdate.setProfit(deptProfit);
                sysDeptMapper.updateDept(sysDeptUpdate);
                //每笔订单用户可分润金额
                String userProportion = configService.selectConfigByKey("userProportion");
                BigDecimal userProfitAmount = profitAmount.multiply(new BigDecimal(userProportion));
                total = total.add(userProfitAmount);

            }
            //用户分润总金额等于  每一笔订单的用户分润金额加昨日结余
            total = total.add(yesterDayBalance);
            //今日结余
            BigDecimal todayBalance = total;
            //如果可分润金额大于0 就分别计算金银铜
            if (total.compareTo(BigDecimal.ZERO) > 0) {
                todayBalance = calculateMoneyByProfitPointType(TradeConstants.GOLD, total, todayBalance);
                todayBalance = calculateMoneyByProfitPointType(TradeConstants.SLIVER, total, todayBalance);
                todayBalance = calculateMoneyByProfitPointType(TradeConstants.COPPER, total, todayBalance);
            }

            TradeProfitFlow tradeProfitFlowInsert = new TradeProfitFlow();
            tradeProfitFlowInsert.setUserProfitAmount(todayBalance.doubleValue());
            tradeProfitFlowInsert.setDate(new Date());
            tradeProfitFlowInsert.setType(TradeConstants.BALANCE);
            tradeProfitFlowDao.insert(tradeProfitFlowInsert);


        } catch (ParseException e) {
            throw new RuntimeException(e);
        }

    }

    @Override
    public BigDecimal selectUserFundPoolTotalAmount() {
        BigDecimal surplus = BigDecimal.valueOf(0);
        //结余
        TradeProfitFlow tradeProfitFlow = tradeProfitFlowDao.selectLastDayBalance();
        if (tradeProfitFlow != null) {
            surplus = surplus.add(BigDecimal.valueOf(tradeProfitFlow.getUserProfitAmount()));
        }
        //用户端当前分润总金额
        BigDecimal totalAmount = tradeProfitFlowDao.selectUserFundPoolTotalAmount();
        if (totalAmount != null) {
            surplus = surplus.add(totalAmount);
        }
        return surplus;
    }

    /**
     * 根据不同的类型  金/银/铜 分别计算其 分润金额
     */
    public BigDecimal calculateMoneyByProfitPointType(String profitPointType, BigDecimal total, BigDecimal todayBalance) {
        //根据类型 匹配分润比例
        BigDecimal weight = BigDecimal.ZERO;
        String typeString = "";
        switch (profitPointType) {
            case TradeConstants.GOLD:
                weight = new BigDecimal(configService.selectConfigByKey("goldProportion"));
                typeString = TradeConstants.GOLDSTRING;
                break;
            case TradeConstants.SLIVER:
                weight = new BigDecimal(configService.selectConfigByKey("sliverProportion"));
                typeString = TradeConstants.SLIVERSTRING;
                break;
            case TradeConstants.COPPER:
                weight = new BigDecimal(configService.selectConfigByKey("copperProportion"));
                typeString = TradeConstants.COPPERSTRING;
                break;
            default:
                break;
        }
        // 金银铜 分别可分总额
        BigDecimal profitPointTypeTotal = total.multiply(weight);

        //查询 不同类型 累计中订单
        TradeUserProfit tradeUserProfitQuery = new TradeUserProfit();
        //设置 查询条件累计状态为累计中
        tradeUserProfitQuery.setProfitFlag(TradeConstants.PROFITFLAG0);
        //设置 牌子类型
        tradeUserProfitQuery.setUserProfitPoint(profitPointType);
        List<TradeUserProfit> tradeUserProfits = tradeUserProfitDao.queryAllByCondition(tradeUserProfitQuery);
        //这种类型的所有股数
        BigDecimal allWeight = BigDecimal.valueOf(tradeUserProfits.stream().mapToInt(TradeUserProfit::getUserProfitWeight).sum());
        if (allWeight.compareTo(BigDecimal.ZERO) == 0) {
            log.info(StringUtils.join(typeString,"牌股数为0"));
            return todayBalance;
        }
        //每一笔股数可以分的钱，向下保存两位小数
        BigDecimal oneAmount = profitPointTypeTotal.divide(allWeight, 2, BigDecimal.ROUND_DOWN);

        //计算分润
        for (TradeUserProfit tradeUserProfit : tradeUserProfits) {
            //用户分润ID
            Long profitId = tradeUserProfit.getProfitId();
            //用户id
            Long userId = tradeUserProfit.getUserId();
            //用户分润股数
            BigDecimal userProfitWeight = BigDecimal.valueOf(tradeUserProfit.getUserProfitWeight());
            //用户最大分润金额
            BigDecimal userMaxProfitWeight = userProfitWeight.multiply(BigDecimal.valueOf(100));
            //用户已经分润总金额
            BigDecimal userProfitAmount = BigDecimal.valueOf(tradeUserProfit.getUserProfitAmount());
            BigDecimal addAmount = oneAmount.multiply(userProfitWeight);


            if (userProfitAmount.compareTo(userMaxProfitWeight) < 0) {
                TradeUserProfit tradeUserProfitUpdate = new TradeUserProfit();
                tradeUserProfitUpdate.setProfitId(profitId);
                tradeUserProfitUpdate.setUserId(userId);
                //实际加的钱
                BigDecimal actualAddAmount = BigDecimal.valueOf(0);
                //判断加入这笔分润之后是否大于 这笔订单最大分润金额，如果小于继续，如果大于等于则 分润加到最大分润金额，剩下的放入结余
                BigDecimal add = userProfitAmount.add(addAmount);
                if (add.compareTo(userMaxProfitWeight) == 0 || add.compareTo(userMaxProfitWeight) > 0) {
                    BigDecimal subtract = userMaxProfitWeight.subtract(userProfitAmount);
                    //实际加的钱
                    actualAddAmount = subtract;
                    //更新这笔订单为 暂停累计
                    tradeUserProfitUpdate.setProfitFlag(TradeConstants.PROFITFLAG1);
                } else {
                    actualAddAmount = addAmount;
                }
                //计算结余   结余等于用户分润总钱数减去这笔实际增加钱数
                //更新用户可提现金额 增加此笔订单分润
                SysUser sysUser = sysUserMapper.selectUserById(userId);
                BigDecimal profit = sysUser.getProfit();
                profit = profit.add(actualAddAmount);
                SysUser sysUserUpdate = new SysUser();
                sysUserUpdate.setUserId(userId);
                sysUserUpdate.setProfit(profit);
                sysUserMapper.updateUser(sysUserUpdate);

                todayBalance = todayBalance.subtract(actualAddAmount);
                tradeUserProfitUpdate.setUserProfitAmount(userProfitAmount.add(actualAddAmount).doubleValue());
                tradeUserProfitUpdate.setUpdateTime(new Date());
                tradeUserProfitDao.update(tradeUserProfitUpdate);
            } else if (userProfitAmount.compareTo(userMaxProfitWeight) == 0 || userProfitAmount.compareTo(userMaxProfitWeight) > 0) {
                //如果已经分润金额 大于或等于最大分润金额 则暂停累计   不做处理
            }
        }
        return todayBalance;
    }


}
